home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '98 presents:
-
- Sega Rally - CD crack by Static Vengeace
-
- Requirements:
- hex editor and full install
-
- Here we go again, another tutorial based on a Sega game. Sega Rally Championship racing is
- alright but needs a Direct3D (or a 3Dfx) patch for more realism and better frame rates. That would be
- nice but, I can live with the recently released MMX enhanced version 2.1 (from the www.sega.com) of the
- game. However, there is one thing I cannot live with and that's the CD check that occurs when I run the
- game. So of course I set out to FiX this minor problem. Then I thought, as long as I know how to crack
- it, I would show you how to do it too. To begin, like the other tutorials on CD checks cracking I have
- done, I will be using W32Dasm (URSoft) to disassemble and trace through this one. So if you would like to
- follow along you will need to use W32Dasm and disasseble rally.exe. Although the code listing is from the
- newer version 2.1, simular steps will work for the version that's on the CD. In fact, I have also included
- the needed edit for both versions at the end of this article.
- Using my favorite method: Go up to the menu bar and select "Refs" and then select "String data
- references" from the drop down menu. From there, grab the slider bar and scroll down checking for strings
- like "Insert..." or "Please insert.." and eventually you'll run across "Please insert Sega Rally CD." So
- let's double click on that string (this will put you in the middle of the routine that checks for the CD)
- and see what we have:
-
- * Referenced by a CALL at Addresses:
- |:004D894C , :004D8C21 <-- Where the calls came from
- |
- :004F7CA0 81EC04020000 sub esp, 00000204
- :004F7CA6 53 push ebx
- :004F7CA7 56 push esi
- :004F7CA8 57 push edi
- :004F7CA9 55 push ebp
-
- * Reference To: KERNEL32.lstrcatA, Ord:0292h
- |
- :004F7CAA 8B2D60541001 mov ebp, dword ptr [01105460]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7DD4(C)
- |
- :004F7CB0 33DB xor ebx, ebx <-- Initialize number of times tries allowed
-
- * Reference To: KERNEL32.GetLogicalDrives, Ord:00FAh <-- Doesn't this line stand out?
- |
- :004F7CB2 FF155C541001 Call dword ptr [0110545C]
- :004F7CB8 89442410 mov dword ptr [esp+10], eax
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7D97(C)
- |
- :004F7CBC B801000000 mov eax, 00000001
- :004F7CC1 8ACB mov cl, bl
- :004F7CC3 D3E0 shl eax, cl
- :004F7CC5 85442410 test dword ptr [esp+10], eax
- :004F7CC9 0F84C4000000 je 004F7D93
- :004F7CCF 8D4341 lea eax, dword ptr [ebx+41]
- :004F7CD2 8D8C2414010000 lea ecx, dword ptr [esp+00000114]
- :004F7CD9 50 push eax
-
- * Possible StringData Ref from Data Obj ->"%c:\" <-- Another common ref string in CD checks
- |
- :004F7CDA 6808916500 push 00659108
- :004F7CDF 51 push ecx
-
- * Reference To: USER32.wsprintfA, Ord:026Dh
- |
- :004F7CE0 FF157C551001 Call dword ptr [0110557C]
- :004F7CE6 8D8C2420010000 lea ecx, dword ptr [esp+00000120]
- :004F7CED 83C40C add esp, 0000000C
- :004F7CF0 51 push ecx
-
- * Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh <-- Common text string to search for
- |
- :004F7CF1 FF1564541001 Call dword ptr [01105464]
- :004F7CF7 83F805 cmp eax, 00000005 <-- Value for CD-ROM drives
- :004F7CFA 0F8593000000 jne 004F7D93
- :004F7D00 8DBC2414010000 lea edi, dword ptr [esp+00000114]
- :004F7D07 B9FFFFFFFF mov ecx, FFFFFFFF
- :004F7D0C 2BC0 sub eax, eax
-
- * Possible StringData Ref from Data Obj ->"srally\rally.exe" <-- The file we check for
- |
- :004F7D0E 6810916500 push 00659110
- :004F7D13 F2 repnz
- :004F7D14 AE scasb
- :004F7D15 F7D1 not ecx
- :004F7D17 2BF9 sub edi, ecx
- :004F7D19 8BC1 mov eax, ecx
- :004F7D1B C1E902 shr ecx, 02
- :004F7D1E 8BF7 mov esi, edi
- :004F7D20 8D7C2418 lea edi, dword ptr [esp+18]
- :004F7D24 F3 repz
- :004F7D25 A5 movsd
- :004F7D26 8BC8 mov ecx, eax
- :004F7D28 83E103 and ecx, 00000003
- :004F7D2B F3 repz
- :004F7D2C A4 movsb
- :004F7D2D 8D4C2418 lea ecx, dword ptr [esp+18]
- :004F7D31 51 push ecx
- :004F7D32 FFD5 call ebp
- :004F7D34 8D442414 lea eax, dword ptr [esp+14]
- :004F7D38 6A00 push 00000000
- :004F7D3A 50 push eax
-
- * Reference To: KERNEL32._lopen, Ord:028Eh
- |
- :004F7D3B FF1568541001 Call dword ptr [01105468]
- :004F7D41 83F8FF cmp eax, FFFFFFFF
- :004F7D44 744D je 004F7D93
- :004F7D46 50 push eax
-
- * Reference To: KERNEL32._lclose, Ord:028Bh
- |
- :004F7D47 FF157C541001 Call dword ptr [0110547C]
- :004F7D4D 8DBC2414010000 lea edi, dword ptr [esp+00000114]
- :004F7D54 B9FFFFFFFF mov ecx, FFFFFFFF
- :004F7D59 2BC0 sub eax, eax
-
- * Possible StringData Ref from Data Obj ->"srally\lake.tex" <-- Check for this one also
- |
- :004F7D5B 6824916500 push 00659124
- :004F7D60 F2 repnz
- :004F7D61 AE scasb
- :004F7D62 F7D1 not ecx
- :004F7D64 2BF9 sub edi, ecx
- :004F7D66 8BC1 mov eax, ecx
- :004F7D68 C1E902 shr ecx, 02
- :004F7D6B 8BF7 mov esi, edi
- :004F7D6D 8D7C2418 lea edi, dword ptr [esp+18]
- :004F7D71 F3 repz
- :004F7D72 A5 movsd
- :004F7D73 8BC8 mov ecx, eax
- :004F7D75 83E103 and ecx, 00000003
- :004F7D78 F3 repz
- :004F7D79 A4 movsb
- :004F7D7A 8D4C2418 lea ecx, dword ptr [esp+18]
- :004F7D7E 51 push ecx
- :004F7D7F FFD5 call ebp
- :004F7D81 8D442414 lea eax, dword ptr [esp+14]
- :004F7D85 6A00 push 00000000
- :004F7D87 50 push eax
-
- * Reference To: KERNEL32._lopen, Ord:028Eh
- |
- :004F7D88 FF1568541001 Call dword ptr [01105468]
- :004F7D8E 83F8FF cmp eax, FFFFFFFF
- :004F7D91 750C jne 004F7D9F
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004F7CC9(C), :004F7CFA(C), :004F7D44(C)
- |
- :004F7D93 43 inc ebx <-- Increase the number of times we tried so far
- :004F7D94 83FB20 cmp ebx, 00000020 <-- We'll try 32 times to check for the file
- :004F7D97 0F8C1FFFFFFF jl 004F7CBC <-- Loop back up and try again
- :004F7D9D EB07 jmp 004F7DA6 <-- Tried all 32 times and STILL no CD
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7D91(C)
- |
- :004F7D9F 50 push eax
-
- * Reference To: KERNEL32._lclose, Ord:028Bh
- |
- :004F7DA0 FF157C541001 Call dword ptr [0110547C]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7D9D(U)
- |
- :004F7DA6 B8FFFFFFFF mov eax, FFFFFFFF <-- Load eax for a failed CD check
- :004F7DAB 83FB20 cmp ebx, 00000020 <-- Did we use all 32 tries
- :004F7DAE 7402 je 004F7DB2 <-- If yes, then leave FFFFFFFF in eax
- :004F7DB0 8BC3 mov eax, ebx <-- Any other value in eax = passed CD check
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7DAE(C)
- |
- :004F7DB2 A39C646500 mov dword ptr [0065649C], eax
- :004F7DB7 83F8FF cmp eax, FFFFFFFF <-- Was the check good or bad?
- :004F7DBA 752B jne 004F7DE7 <-- Take this jump for CD check=passed
- :004F7DBC 6A35 push 00000035
-
- * Possible StringData Ref from Data Obj ->"SEGA RALLY CHAMPIONSHIP for PC"
- |
- :004F7DBE A170646500 mov eax, dword ptr [00656470]
- :004F7DC3 50 push eax
-
- * Possible StringData Ref from Data Obj ->"Please insert Sega Rally CD." <-- The string we don't want
- | <-- to ever see..
- :004F7DC4 6834916500 push 00659134
- :004F7DC9 6A00 push 00000000
-
- * Reference To: USER32.MessageBoxA, Ord:019Bh
- |
- :004F7DCB FF15EC551001 Call dword ptr [011055EC]
- :004F7DD1 83F802 cmp eax, 00000002 <-- 02 means "we" pressed cancel
- :004F7DD4 0F85D6FEFFFF jne 004F7CB0 <-- This jump loops back up to recheck
- :004F7DDA 33C0 xor eax, eax <-- Set eax to zero for failed CD check
- :004F7DDC 5D pop ebp
- :004F7DDD 5F pop edi
- :004F7DDE 5E pop esi
- :004F7DDF 5B pop ebx
- :004F7DE0 81C404020000 add esp, 00000204
- :004F7DE6 C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004F7DBA(C)
- |
- :004F7DE7 B801000000 mov eax, 00000001 <-- Load eax with 01 for a passed CD check
- :004F7DEC 5D pop ebp
- :004F7DED 5F pop edi
- :004F7DEE 5E pop esi
- :004F7DEF 5B pop ebx
- :004F7DF0 81C404020000 add esp, 00000204
- :004F7DF6 C3 ret
-
- That seems straight forward when you take into acount the couple of comments
- I made as to what's going on. So lets check the code that calls the above routine.
- First comes the code from 4D894C:
-
- :004D8943 A1C0646500 mov eax, dword ptr [006564C0]
- :004D8948 A804 test al, 04
- :004D894A 7515 jne 004D8961
- :004D894C E84FF30100 call 004F7CA0 <-- Call the CD check routine
- :004D8951 85C0 test eax, eax <-- Check to see what came back in eax
- :004D8953 750C jne 004D8961 <-- Take this jump for good CD check
- :004D8955 33C0 xor eax, eax <-- Zero out eax
- :004D8957 5D pop ebp
- :004D8958 5F pop edi
- :004D8959 5E pop esi
- :004D895A 5B pop ebx
- :004D895B 83C450 add esp, 00000050
- :004D895E C21000 ret 0010 <-- Exit back to Win95
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004D894A(C), :004D8953(C)
- |
- :004D8961 33ED xor ebp, ebp <-- Continues on with the game
- :004D8963 E8584BFCFF call 0049D4C0
- :004D8968 E8534BFCFF call 0049D4C0
- :004D896D E8DEEE0100 call 004F7850
- :004D8972 E8F9F50100 call 004F7F70
- :004D8977 55 push ebp
-
- * Reference To: USER32.GetSystemMetrics, Ord:012Ch
- |
- :004D8978 8B1D3C561001 mov ebx, dword ptr [0110563C]
- :004D897E FFD3 call ebx
- :004D8980 6A01 push 00000001
- :004D8982 A344416600 mov dword ptr [00664144], eax
- :004D8987 FFD3 call ebx
- -- more program code --
-
- Alright, from here we can kill the call to the CD check routine by NOP'ing it out at 4D894C and
- changing the conditional jump to an unconditional jump so the game will always continue. But look at the
- conditional jump at 4D894A! It takes us right to the contiune section and jumps over the CD check in the
- process. Great!, we will make use of it and change that conditional jump to an unconditional jump also.
- So let's go on to the other section of code that calls the "check for original CD" routine at 4D8C21 with
- some surrounding code:
-
- :004D8C18 A1C0646500 mov eax, dword ptr [006564C0]
- :004D8C1D A804 test al, 04
- :004D8C1F 7515 jne 004D8C36 <-- Another conditional jump past it all
- :004D8C21 E87AF00100 call 004F7CA0 <-- Call the "insert CD" routine
- :004D8C26 85C0 test eax, eax <-- Check to see what came back in eax
- :004D8C28 750C jne 004D8C36 <-- Take this jump for good CD check
- :004D8C2A 33C0 xor eax, eax <-- Zero out eax
- :004D8C2C 5D pop ebp
- :004D8C2D 5F pop edi
- :004D8C2E 5E pop esi
- :004D8C2F 5B pop ebx
- :004D8C30 83C450 add esp, 00000050
- :004D8C33 C21000 ret 0010 <-- Exit back to Win95
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004D8C1F(C), :004D8C28(C)
- |
- :004D8C36 C744241000000000 mov [esp+10], 00000000 <-- Continue with the game
- :004D8C3E 56 push esi
- :004D8C3F 68007E4F00 push 004F7E00
-
- * Reference To: USER32.EnumWindows, Ord:00C8h
- |
- :004D8C44 FF1528561001 Call dword ptr [01105628]
- :004D8C4A 8B442410 mov eax, dword ptr [esp+10]
- -- more program code --
-
- Nearly the same as the first section we examined and well make the same type of edit for this
- one also. The program checks for CD once per gaming session, then sets a flag value at 6564C0 that
- tells rally the CD is present and already has been checked for. Then as you play the game rally checks
- 6564C0 and if set correctly skips checking for the CD again. Which is useful to us in removing the check
- from the game. Instead of relying on the conditional jump to skip over the CD check, we'll change it to
- always jump over the CD check call. Then NOP'ing out the call to the CD checking routine and forcing the
- following conditional jump is overkill, but that's ok I added it in anyways. Now all you need to do is
- make the patch to the rally.exe file by version:
-
- For the version off the CD, edit rally.exe
- =============================================================
- Search for: 75 15 E8 81 62 FF FF 85 C0 75 0C (offset 235,304)
- Change to : EB -- 90 90 90 90 90 -- -- EB --
-
- Search for: 75 15 E8 B1 5F FF FF 85 C0 75 0C (offset 236,024)
- Change to : EB -- 90 90 90 90 90 -- -- EB --
-
-
- For the MMX Enhanced version 2.1, edit rally.exe
- =============================================================
- Search for: 75 15 E8 4F F3 01 00 85 C0 75 0C (offset 884,042)
- Change to : EB -- 90 90 90 90 90 -- -- EB --
-
- Search for: 75 15 E8 7A F0 01 00 85 C0 75 0C (offset 884,767)
- Change to : EB -- 90 90 90 90 90 -- -- EB --
-
- Once again I helped guide you through another example of a CD check and showed you a way to defeat
- it. The end result is a copy of Rally Championship on your hard drive that you can run without having to
- dig out the original game CD first. Well, there you have it, Sega Rally is now FiX'ed
-
- Static Vengeance
-